import os
import subprocess
import sys
import argparse

# 第一部分：定义默认变量
# 默认输出的文件名
DEFAULT_OUTPUT_FILE = "win-tools.exe"
# 默认入口文件的位置
DEFAULT_ENTRY_FILE = "./main.go"
# 默认构建时的链接器标志
DEFAULT_LDFLAGS = "-s -w"


# 第二部分：函数区
def check_go_installed():
    """检查是否安装了 Go 编译器"""
    try:
        subprocess.run(["go", "version"], capture_output=True, text=True, check=True)
        print("Go 编译器已安装。")
        return True
    except subprocess.CalledProcessError:
        print("未检测到 Go 编译器，请确保已安装并添加到 PATH 中。")
        return False


def check_go_mod_file():
    """检查当前目录是否存在 go.mod 文件"""
    if os.path.exists("go.mod"):
        print("go.mod 文件存在。")
        return True
    else:
        print("当前目录下未找到 go.mod 文件。")
        return False


def check_entry_file(entry_file):
    """检查指定的入口文件是否存在"""
    if os.path.exists(entry_file):
        print(f"入口文件 {entry_file} 存在。")
        return True
    else:
        print(f"未找到入口文件 {entry_file}。")
        return False


def run_go_mod_tidy():
    """执行 go mod tidy 并处理输出"""
    try:
        subprocess.run(
            ["go", "mod", "tidy"], capture_output=True, text=True, check=True
        )
        print("go mod tidy 执行成功。")
    except subprocess.CalledProcessError as e:
        print("go mod tidy 执行失败：")
        print(e.stderr.strip())
        sys.exit(1)


def run_go_vet():
    """执行 go vet 检查代码并处理输出"""
    try:
        subprocess.run(
            ["go", "vet", "./..."], capture_output=True, text=True, check=True
        )
        print("go vet 检查成功。")
    except subprocess.CalledProcessError as e:
        print("go vet 检查失败：")
        print(e.stderr.strip())
        sys.exit(1)


def run_gofmt():
    """执行 gofmt -w . 格式化代码"""
    try:
        subprocess.run(["gofmt", "-w", "."], capture_output=True, text=True, check=True)
        print("代码格式化成功。")
    except subprocess.CalledProcessError as e:
        print("代码格式化失败：")
        print(e.stderr.strip())
        sys.exit(1)


def build_go_app(output_file, entry_file, ldflags):
    """组装并执行构建命令"""
    try:
        # 使用指定的链接器标志进行构建
        subprocess.run(
            ["go", "build", "-o", output_file, "-ldflags", ldflags, entry_file],
            capture_output=True,
            text=True,
            check=True,
        )
        print(f"构建成功，输出文件：{output_file}。")
        return True
    except subprocess.CalledProcessError as e:
        print("构建失败：")
        print(e.stderr.strip())
        return False


# 第三部分：main 函数
def main():
    # 解析命令行参数
    parser = argparse.ArgumentParser(description="构建 Go 应用程序")
    parser.add_argument(
        "-o", "--output", help="指定输出文件名", default=DEFAULT_OUTPUT_FILE
    )
    parser.add_argument(
        "-e", "--entry", help="指定入口文件路径", default=DEFAULT_ENTRY_FILE
    )
    parser.add_argument(
        "-l", "--ldflags", help="指定构建时的链接器标志", default=DEFAULT_LDFLAGS
    )
    args = parser.parse_args()

    output_file = args.output
    entry_file = args.entry
    ldflags = args.ldflags

    print("开始构建 Go 应用程序...")

    # 检查 Go 编译器是否安装
    if not check_go_installed():
        sys.exit(1)

    # 检查 go.mod 文件是否存在
    if not check_go_mod_file():
        sys.exit(1)

    # 检查入口文件是否存在
    if not check_entry_file(entry_file):
        sys.exit(1)

    # 执行 go mod tidy
    run_go_mod_tidy()

    # 执行 go vet
    run_go_vet()

    # 执行 gofmt -w . 格式化代码
    run_gofmt()

    # 执行构建命令
    if build_go_app(output_file, entry_file, ldflags):
        print("构建完成。")
    else:
        print("构建失败，请检查错误信息。")


if __name__ == "__main__":
    main()
